//////////////////////////////////////////////////////////////////////////////////
// Who  : Lim, Dong-moon (dmlim@nate.com, 011-701-9381)
// When : 2006/??/??
//////////////////////////////////////////////////////////////////////////////////

#ifndef __NCRYPT_OPENSSL_H__
#define __NCRYPT_OPENSSL_H__

#ifdef WIN32

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <windows.h>
//#include <wincrypt.h>
#include <crtdbg.h>
#include <tchar.h>
#include <nblob.h>

#pragma warning( disable : 4786 )

#endif // WIN32

#include <ncrypt_types.h>
#include <ncrypt_verify.h>
#include <nblob.h>

#if defined(WIN32) && !defined(USE_OPENSSL)
#else
#include <openssl/rsa.h>
#endif

int openssl_init();
int openssl_final();

int ALG_MS_2_OPENSSL(ALG_ID algid);
ALG_ID ALG_OPENSSL_2_MS(int nid);

void openssl_GetSupportedAlgs(
	const ALG_ID* pPreferAlgs, 
	DWORD cPreferLen,
	ALG_ID** ppSupportAlgs, 
	DWORD* pcSupportLen
);

BOOL openssl_ReadPEMPrivateKey(
	LPCTSTR lpszPKFile, 
	LPCSTR lpszPasswd, 
	RSA** ppRSAKey);

BOOL openssl_HashRandomAndSessionKey(
	DWORD cbRandom,
	const BYTE* pbRandom,
	DWORD cbSessionKey,
	const BYTE* pbSessionKey,
	DWORD* pcbHash,
	BYTE** ppbHash); 

BOOL openssl_MyEncrypt(
	const BYTE* pbSessionKey,
	ALG_ID m_cryptAlg,
	const BYTE* pbInData,
	DWORD dwInDataLen,
	BYTE** ppbOutData,
	DWORD* pdwOutDataLen);

BOOL openssl_MyDecrypt(
	const BYTE* pbSessionKey,
	ALG_ID m_cryptAlg,
	const BYTE* pbInData,
	DWORD dwInDataLen,
	BYTE** ppbOutData,
	DWORD* pdwOutDataLen);

// with IV

BOOL openssl_MyEncrypt(
	const BYTE* pbSessionKey,
	const BYTE* pbIV,
	ALG_ID m_cryptAlg,
	const BYTE* pbInData,
	DWORD dwInDataLen,
	BYTE** ppbOutData,
	DWORD* pdwOutDataLen);

BOOL openssl_MyDecrypt(
	const BYTE* pbSessionKey,
	const BYTE* pbIV,
	ALG_ID m_cryptAlg,
	const BYTE* pbInData,
	DWORD dwInDataLen,
	BYTE** ppbOutData,
	DWORD* pdwOutDataLen);

BOOL openssl_MyHash(
	ALG_ID algId,
	const BYTE* pbDataIn,
	DWORD cbDataIn,
	BYTE** ppbHashOut,
	DWORD* pcbDataOut
	);

BOOL openssl_CHashSaltPswd(
	const BYTE* pbSalt,
	DWORD cbSalt,
	LPCTSTR passwd,
	BYTE** ppbHash,
	DWORD* pcbHash
	);

BOOL openss_CHashSaltPswd40(
	const BYTE* pbSalt,
	DWORD cbSalt,
	LPCTSTR passwd,
	BYTE** ppbHash,
	DWORD* pcbHash
	);

BOOL openssl_MyDeriveKey(
	ALG_ID algId,
	const BYTE* pbSalt,
	DWORD cbSalt,
	LPCTSTR passwd,
	DWORD cbKey,
	BYTE** ppbKey
	);

BOOL openssl_InsertCertsIntoStore(LPCTSTR filename, X509_STORE *pStore);
BOOL openssl_ReadCertsFromMemory(int len, NBLOB* pBlobs, STACK_OF(X509)** pCerts);
BOOL openssl_ReadCertFromMemory(BYTE* pData, DWORD cSize, X509** pCert);
BOOL openssl_ReadCertsFromFile(LPCTSTR filename, STACK_OF(X509)** pCerts);
BOOL openssl_ReadCertFromFile(LPCTSTR filename, X509** pCert);
BOOL openssl_VerifyHostName(X509 *cert, HostNameVerifyCallback fn, LPVOID ctx);
BOOL openssl_VerifyCertificate(NBLOB* pCert, int nChainsLen, NBLOB* pChains, LPCTSTR szCAFile, HostNameVerifyCallback fn, LPVOID ctx);

#endif // __NCRYPT_OPENSSL_H__
